import 'dart:async';
//import 'dart:ffi';
import 'dart:math';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'dart:io' show Platform;
import 'package:flutter_baidu_mapapi_base/flutter_baidu_mapapi_base.dart'
    show BMFCoordinate, BMFEdgeInsets, BMFMapSDK, BMFPoint, BMF_COORD_TYPE;
import 'package:flutter_baidu_mapapi_map/flutter_baidu_mapapi_map.dart';
import 'package:flutter_baidu_mapapi_search/flutter_baidu_mapapi_search.dart';
import 'package:flutter_bmflocation/bdmap_location_flutter_plugin.dart';
import 'package:flutter_bmflocation/flutter_baidu_location.dart';
import 'package:flutter_bmflocation/flutter_baidu_location_android_option.dart';
import 'package:flutter_bmflocation/flutter_baidu_location_ios_option.dart';
import 'package:geolocator/geolocator.dart';

class ScreeSize {
  static double width;
  static double height;
}

class LlComputeDistanceUtils {
  static final double PI = pi; //3.141593;

  static final double PK = 180 / PI;

  /**
   * @Description: 根据经纬度计算两点之间的距离
   *
   * @param lat_a a的经度
   * @param lng_a a的维度
   * @param lat_b b的经度
   * @param lng_b b的维度
   * @return 距离
   * @author yangzhenlong
   */
  static int getDistance(
      double lat_a, double lng_a, double lat_b, double lng_b) {
    double t1 =
        cos(lat_a / PK) * cos(lng_a / PK) * cos(lat_b / PK) * cos(lng_b / PK);
    double t2 =
        cos(lat_a / PK) * sin(lng_a / PK) * cos(lat_b / PK) * sin(lng_b / PK);
    double t3 = sin(lat_a / PK) * sin(lat_b / PK);

    double tt = acos(t1 + t2 + t3);
    return (6366000 * tt).round();
  }
}

void main() {
  //百度地图sdk初始化鉴权
  if (Platform.isIOS) {
    BMFMapSDK.setApiKeyAndCoordType(
        '请输入百度开放平台申请的iOS端API KEY', BMF_COORD_TYPE.BD09LL);
  } else if (Platform.isAndroid) {
    BMFMapSDK.setCoordType(BMF_COORD_TYPE.BD09LL);
  }

  runApp(MyApp());
}

LocationFlutterPlugin _locationPlugin = new LocationFlutterPlugin();

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '快地图',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // final Geolocator geolocator = Geolocator()
  //   ..forceAndroidLocationManager; //首次获取城市名的第三方库
  TextEditingController _searchTextControl = TextEditingController();

  //当前位置
  BMFCoordinate coordinate = BMFCoordinate(0, 0);
  BMFMapController _mapController = null;

  Map<String, Object> _loationResult;
  BaiduLocation _baiduLocation; // 定位结果
  StreamSubscription<Map<String, Object>> _locationListener;
  String _city;
  @override
  void initState() {
    super.initState();

    //动态申请定位权限，避免要自己写几个权限的申请代码
    _locationPlugin.requestPermission();

    _locationListener =
        _locationPlugin.onResultCallback().listen((Map<String, Object> result) {
      setState(() {
        _loationResult = result;
        try {
          _baiduLocation =
              BaiduLocation.fromMap(result); // 将原生端返回的定位结果信息存储在定位结果类中
          print('-----------设备定时1.5秒定位一次-----------');
          //setScanspan里设置的
          _updateLoc(_baiduLocation.latitude, _baiduLocation.longitude);
        } catch (e) {
          print(e);
        }
      });
    });

    try {
      _setLocOption();
      //启动定时定位功能
      _locationPlugin.startLocation();
    } catch (e) {}
  }

  /// 设置android端和ios端定位参数
  void _setLocOption() {
    /// android 端设置定位参数
    BaiduLocationAndroidOption androidOption = new BaiduLocationAndroidOption();
    androidOption.setCoorType("bd09ll"); // 设置返回的位置坐标系类型
    androidOption.setIsNeedAltitude(false); // 设置是否需要返回海拔高度信息
    androidOption.setIsNeedAddres(true); // 设置是否需要返回地址信息
    androidOption.setIsNeedLocationPoiList(true); // 设置是否需要返回周边poi信息
    androidOption.setIsNeedNewVersionRgc(true); // 设置是否需要返回最新版本rgc信息
    androidOption.setIsNeedLocationDescribe(true); // 设置是否需要返回位置描述
    androidOption.setOpenGps(true); // 设置是否需要使用gps
    androidOption.setLocationMode(LocationMode.Hight_Accuracy); // 设置定位模式
    androidOption.setScanspan(1500); // 设置发起定位请求时间间隔

    Map androidMap = androidOption.getMap();

    /// ios 端设置定位参数
    BaiduLocationIOSOption iosOption = new BaiduLocationIOSOption();
    iosOption.setIsNeedNewVersionRgc(true); // 设置是否需要返回最新版本rgc信息
    iosOption.setBMKLocationCoordinateType(
        "BMKLocationCoordinateTypeBMK09LL"); // 设置返回的位置坐标系类型
    iosOption.setActivityType("CLActivityTypeAutomotiveNavigation"); // 设置应用位置类型
    iosOption.setLocationTimeout(10); // 设置位置获取超时时间
    iosOption.setDesiredAccuracy("kCLLocationAccuracyBest"); // 设置预期精度参数
    iosOption.setReGeocodeTimeout(10); // 设置获取地址信息超时时间
    iosOption.setDistanceFilter(100); // 设置定位最小更新距离
    iosOption.setAllowsBackgroundLocationUpdates(true); // 是否允许后台定位
    iosOption.setPauseLocUpdateAutomatically(true); //  定位是否会被系统自动暂停

    Map iosMap = iosOption.getMap();

    _locationPlugin.prepareLoc(androidMap, iosMap);
  }

  //定位按钮点击，具体功能依赖1.5s的定时执行结果
  void _locationAct() {
    _moveCameraAfterClick = true;
  }

  bool _moveCameraAfterClick = false; //每次点击定位按钮，移动镜头视角
  bool _loadFirst = true; //第一次初始化定位后也要移动镜头视角
  void _updateLoc(double x, double y) async {
    coordinate = BMFCoordinate(x, y);

    BMFLocation location = new BMFLocation(
        coordinate: coordinate,
        altitude: 0,
        horizontalAccuracy: 5,
        verticalAccuracy: -1.0,
        speed: -1.0,
        course: -1.0);

    BMFUserLocation userLocation = BMFUserLocation(
      location: location,
    );

    BMFUserLocationDisplayParam displayParam = BMFUserLocationDisplayParam(
        locationViewOffsetX: 0,
        locationViewOffsetY: 0,
        accuracyCircleFillColor: Colors.red,
        accuracyCircleStrokeColor: Colors.blue,
        isAccuracyCircleShow: true,
        locationViewImage: 'assets/images/ima_mine5.png',
        locationViewHierarchy:
            BMFLocationViewHierarchy.LOCATION_VIEW_HIERARCHY_BOTTOM);

    //摄像头中心位置，只是在点击“点击”按钮时，才重新恢复
    if (_moveCameraAfterClick == true) {
      _mapController.setCenterCoordinate(coordinate, true);
      _moveCameraAfterClick = false;
    }
    //第一次定位，不仅要直接把视角移到中心；要把城市名也带过来,为后面poi查询做准备
    if (_loadFirst == true) {
      _mapController.setCenterCoordinate(coordinate, true);
      _loadFirst = false;
      //List<Placemark> p = await geolocator.placemarkFromCoordinates(
      //    coordinate.latitude, coordinate.longitude);
      //Placemark place = p[0];
      // _city = place.locality;
    }

    //更新实时位置的点
    _mapController?.updateLocationData(userLocation);
    _mapController?.updateLocationViewWithParam(displayParam);
  }

  @override
  void dispose() {
    super.dispose();
    if (null != _locationListener) {
      _locationListener.cancel(); // 停止定位
    }
  }

  /// 地图一进来创建完成回调
  void onBMFMapCreated(BMFMapController controller) {
    _mapController = controller;
    _mapController.setUserTrackingMode(null,
        enableDirection: true, customMarker: null);
    _mapController.showUserLocation(true);

    /// 地图加载回调
    _mapController?.setMapDidLoadCallback(callback: () {
      print('mapDidLoad-地图加载完成');
    });
  }

  List<BMFMarker> markers = [];
  List<BMFPoiInfo> addressDetails = [];
  //poi周边搜索
  void _search() async {
    BMFPoiNearbySearchOption poiCitySearchOption =
        //BMFPoiCitySearchOption(city: '南京', keyword: '新街口');
        // BMFPoiCitySearchOption(
        //    city: _city, keyword: this._searchTextControl.text);
        BMFPoiNearbySearchOption(
            pageSize: 20,
            scope: BMFPoiSearchScopeType.DETAIL_INFORMATION,
            keywords: [this._searchTextControl.text],
            location: coordinate,
            radius: 60000); //只查询60公里以内的
    // 检索实例
    BMFPoiNearbySearch poiCitySearch = BMFPoiNearbySearch();
    // 检索回调
    poiCitySearch
      ..onGetPoiNearbySearchResult(
          callback: (BMFPoiSearchResult result, BMFSearchErrorCode errorCode) {
        if (result == null || errorCode != BMFSearchErrorCode.NO_ERROR) {
          return;
        }
        try {
          /// 添加poi marker（地图标记，如一个餐厅）
          int i = 0;
          markers.clear();
          addressDetails.clear();
          for (BMFPoiInfo poiInfo in result.poiInfoList) {
            if (i > 0) break;
            var temp = BMFPoiInfo(
                address: poiInfo.address, name: poiInfo.name, pt: poiInfo.pt);
            //手动计算记录，根据经纬度，后续要排序用
            temp.distance = LlComputeDistanceUtils.getDistance(
                coordinate.latitude,
                coordinate.longitude,
                poiInfo.pt.latitude,
                poiInfo.pt.longitude);
            addressDetails.add(temp);
          }

          try {
            //根据距离排序
            addressDetails
                .sort((left, right) => left.distance.compareTo(right.distance));
            for (var i in addressDetails) {
              var marker = BMFMarker(
                  position: i.pt,
                  title: i.name,
                  icon: "assets/images/ima_mark3.png");
              markers.add(marker);
            }
          } catch (e) {
            //sdg
          }

          //直接展示先近处的
          _mapController?.cleanAllMarkers();
          _mapController?.addMarkers(markers);
          _mapController?.setCenterCoordinate(markers.first.position, true);

          //展示底部查询结果列表
          _showBottomDialog();
        } catch (e) {
          print('------------0-------------');
        }
        //print(
        //`poi城市检索回调 errorCode = ${errorCode}  \n result = ${result?.toMap()}`
        //);
        // 解析reslut，具体参考demo
      });
    // 发起检索
    //bool flag = await poiCitySearch.poiCitySearch(poiCitySearchOption);
    bool flag = await poiCitySearch.poiNearbySearch(poiCitySearchOption);
  }

  void _showBottomDialog() {
    showModalBottomSheet(
        context: context,
        builder: (BuildContext context) {
          return ListView.builder(
              itemCount: addressDetails.length,
              itemBuilder: (BuildContext ctx, int position) {
                return getItem(position, ctx);
              });
        });
  }

  BMFMapOptions mapOptions = null;
  @override
  Widget build(BuildContext context) {
    if (ScreeSize.width == null) {
      ScreeSize.width = MediaQuery.of(context).size.width;
      ScreeSize.height = MediaQuery.of(context).size.height;
    }
    if (mapOptions == null) {
      BMFPoint zn = new BMFPoint(60, 10);
      mapOptions = BMFMapOptions(
          center: BMFCoordinate(39.917215, 116.380341),
          zoomLevel: 18,
          trafficEnabled: true,
          compassEnabled: true,
          compassPosition: zn,
          mapPadding: BMFEdgeInsets(left: 30, top: 0, right: 30, bottom: 0));
    }
    return SafeArea(
        child: Scaffold(
            //防止软键盘把地图顶上去
            resizeToAvoidBottomInset: false,
            backgroundColor: Colors.blue,
            body: Container(
              height: ScreeSize.height,
              width: ScreeSize.width,
              child: Stack(
                  //alignment: Alignment.center,
                  children: <Widget>[
                    //百度地图
                    BMFMapWidget(
                      onBMFMapCreated: (controller) {
                        onBMFMapCreated(controller);
                      },
                      mapOptions: mapOptions,
                    ),
                    Container(
                        margin: EdgeInsets.fromLTRB(10, 10, 10, 10),
                        //height: 80,
                        child: Row(
                            //verticalDirection: VerticalDirection.down,
                            //mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            crossAxisAlignment: CrossAxisAlignment.center,
                            children: <Widget>[
                              new TextButton(
                                style: ButtonStyle(backgroundColor:
                                    MaterialStateProperty.resolveWith((states) {
                                  //设置按下时的背景颜色
                                  if (states.contains(MaterialState.pressed)) {
                                    return Color(0xCF1d7cf1);
                                  }
                                  //默认不使用背景颜色
                                  return Color(0xCFa0c1ea);
                                })),
                                child: Text('定位'),
                                onPressed: () {
                                  _locationAct();
                                  print('--------');
                                },
                              ),
                              SizedBox(width: 5),
                              Expanded(
                                  flex: 1,
                                  child: TextField(
                                    decoration: InputDecoration(
                                        fillColor: Color(0xCFeaf0c3),
                                        filled: true),
                                    controller: this._searchTextControl,
                                    onChanged: (value) {},
                                  )),
                              SizedBox(width: 5),
                              TextButton(
                                  style: ButtonStyle(backgroundColor:
                                      MaterialStateProperty.resolveWith(
                                          (states) {
                                    //设置按下时的背景颜色
                                    if (states
                                        .contains(MaterialState.pressed)) {
                                      return Color(0xCF1d7cf1);
                                    }
                                    //默认不使用背景颜色
                                    return Color(0xCFa0c1ea);
                                  })),
                                  child: Text('搜索'),
                                  onPressed: () {
                                    print('---------------00-------------');
                                    _search();
                                  })
                            ])),
                    Positioned(
                        child: Text(
                          '蔡雪所有2021',
                          style: TextStyle(
                            fontWeight: FontWeight.bold,
                            fontSize: 15,
                            color: Color(0xCF4594f6),
                          ),
                        ),
                        bottom: 1,
                        left: 70)
                  ]),
            )));
  }

  Widget getItem(int pos, BuildContext ctx) {
    return GestureDetector(
        child: Container(
            padding: EdgeInsets.all(0),
            color: Colors.transparent,
            child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: [
                  Container(
                      margin: EdgeInsets.only(
                          left: 10, top: 8, bottom: 8, right: 10),
                      child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Row(
                                crossAxisAlignment: CrossAxisAlignment.center,
                                children: [
                                  Text(addressDetails[pos].name),
                                  Expanded(child: Text('')),
                                  Text(
                                    (addressDetails[pos].distance).toString() +
                                        '米',
                                    style: TextStyle(
                                      color: Colors.blue, // 文字颜色
                                    ),
                                  )
                                ]),
                            Text(addressDetails[pos].address),
                          ])),
                  Container(
                    alignment: Alignment.bottomCenter,
                    margin: EdgeInsets.only(
                        left: 20.0, top: 0, right: 20.0, bottom: 0),
                    height: 0.4,
                    color: Colors.grey,
                  )
                ])),
        //item 点击事件
        onTap: () {
          //print("点击到第" + pos.toString());
          Navigator.pop(ctx);
          setState(() {
            _searchTextControl.text = addressDetails[pos].name;

            _mapController?.cleanAllMarkers();
            _mapController?.addMarkers([markers[pos]]);
            _mapController?.setCenterCoordinate(markers[pos].position, true);
            //onItemClick(index);
          });
        });
  }
}
